#ifndef QUEUE_H_
#define QUEUE_H_

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>

template<typename T> struct QueueRecord {
	long mtype;
	T data;
};

template<class T> class Queue {
	private:
		key_t	key;
		int		id;

	public:
		Queue(char* file, char character);
		~Queue();
		void destroy();
		int write(long type, T data);
		int read(long& type, T& data);
};

template<class T> Queue<T>::Queue(char* file, char character) {
	this->key = ftok(file, character);
	if (this->key == -1)
		perror ("Error in ftok");

	this->id = msgget(this->key, 0666|IPC_CREAT);
	if (this->id == -1)
		perror ("Error in msgget");
}

template<class T> Queue<T>::~Queue() {
}

template<class T> void Queue<T>::destroy() {
	msgctl(this->id, IPC_RMID, NULL);
}

template<class T> int Queue<T>::write(long type, T data) {
	QueueRecord<T> queueRecord;
	queueRecord.mtype = type;
	queueRecord.data = data;

	int result = msgsnd(this->id, (const void *)&queueRecord, sizeof(T), 0);
	return result;
}

template<class T> int Queue<T>::read(long& type, T& data) {
	QueueRecord<T> queueRecord;

	int result = msgrcv(this->id, (void *)&queueRecord, sizeof(T), type, 0);
	type = queueRecord.mtype;
	data = queueRecord.data;

	return result;
}

#endif /* QUEUE_H_ */
